home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / ISSUE22 / TIMING / PROFIT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-02-21  |  9.3 KB  |  494 lines

  1. unit PROFIT;
  2.  
  3. { This is a unit to permit various profiling strategies }
  4.  
  5.  
  6.  
  7. interface
  8.  
  9.  
  10.  
  11.  
  12. { Conditional defines must include definitions for profiling as follows:
  13.  
  14.  
  15.     Definition               Action
  16.     ----------------------------------------------------------------
  17.     TMPR                     Causes the timing profiler to be linked
  18.     PrinterPortProfiler      Causes the timing profiler to be linked
  19.     ----------------------------------------------------------------
  20.  }
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28. { PrinterPort profiler }
  29. { ---------------------------------------------------------------- }
  30.  
  31.  
  32. { This permits the use of the parallel printer port as a
  33.   program profiling aid. It uses toggling D0 of the printer data to
  34.   indicate program activity without incurring speed or compatibility
  35.   problems. }
  36.  
  37. { Port details:
  38.       Data:
  39.          |7|6|5|4|3|2|1|0|  ports 278, 378 (LPT1), 3BC
  40.           | | | | | | | +---- data bit 0, hardware pin 2
  41.           | | | | | | +----- data bit 1, hardware pin 3
  42.           | | | | | +------ data bit 2, hardware pin 4
  43.           | | | | +------- data bit 3, hardware pin 5
  44.           | | | +-------- data bit 4, hardware pin 6
  45.           | | +--------- data bit 5, hardware pin 7
  46.           | +---------- data bit 6, hardware pin 8
  47.           +----------- data bit 7, hardware pin 9
  48.  
  49.  
  50.         Port 3BD printer status register   (Parallel Printer Port)
  51.  
  52.          ª7ª6ª5ª4ª3ª2ª1ª0ª  ports 279, 379 (LPT1), 3BD
  53.           | | | | | | | +---- 1 = time-out
  54.           | | | | | |------- unused
  55.           | | | | +-------- 1 = error,  pin 15
  56.           | | | +--------- 1 = on-line,  pin 13
  57.           | | +---------- 1 = out of paper,  pin 12
  58.           | +----------- 0 = Acknowledge,  pin 10
  59.           +------------ 0 = busy,  pin 11
  60.  
  61.    All signals relative to ground, pins 18..25 inc.
  62.  
  63. }
  64.  
  65. const
  66.  ioAdr1 = $378;
  67.  ioAdr2 = $278;
  68.  ioAdr3 = $3BC;
  69.  
  70. procedure PPPRInitialise( APortAddress : word );
  71. { Opens the printer port setting defaults }
  72. procedure PPPRSetAllBits;
  73. { Sets the port to all data bits = 1 }
  74. procedure PPPRClearAllBits;
  75. { Sets the port to all data bits = 0 }
  76. procedure PPPRToggleAllBits;
  77. { Complements all data bits }
  78. procedure PPPRWriteAllBits( APattern : byte );
  79. { Sets this pattern on the data }
  80. function  bfunc_PPPRBusyIsHigh : boolean;
  81. { Returns TRUE if the busy input is high }
  82. function  bfunc_PPPRBusyIsLow : boolean;
  83. { Returns TRUE if the busy input is low }
  84. procedure PPPRSetDefaults;
  85. { Sets the port into a defined state }
  86.  
  87. { End of PrinterPort profiler }
  88. { ---------------------------------------------------------------- }
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100. { Timing profiler }
  101. { ---------------------------------------------------------------- }
  102. procedure TMPROpen( const AFileName : string;
  103.                           AMaxItems : integer );
  104. { Opens the timing profiler }
  105. procedure TMPRStart;
  106. { Resets the timing profiler }
  107. procedure TMPRMark( ACode : integer );
  108. { Marks this profile point }
  109. procedure TMPRClose;
  110. { Closes the timing profiler }
  111.  
  112. { End of Timing profiler }
  113. { ---------------------------------------------------------------- }
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121. implementation
  122.  
  123. {$I LibDef.inc}
  124.  
  125.  
  126. {$IFDEF TMPR }
  127.  
  128.   {$IFDEF TargetDelphi}
  129.   uses
  130.   HiResTmr,
  131.   Winprocs,
  132.   WinTypes,
  133.   SysUtils;
  134.   {$ENDIF}
  135.  
  136.   {$IFDEF TargetDOSMode}
  137.   uses
  138.   HiResTmr,
  139.   Objects;
  140.   {$ENDIF}
  141.  
  142.  
  143. {$ENDIF}
  144.  
  145.  
  146.  
  147.  
  148.  
  149.  
  150. { PrinterPort profiler }
  151. { ---------------------------------------------------------------- }
  152.  
  153. {$IFDEF PrinterPortProfiler }
  154.  
  155.  
  156. const
  157.  by_PPPRExistingPattern : byte = 0;
  158.  w_PPTAdr : word = ioAdr1;
  159.  
  160.  
  161. procedure   WriteIOByte( AData : byte; AAddress : word); assembler;
  162. {$IFDEF Target16Bit}
  163.   asm
  164.   mov dx,AAddress;
  165.   mov al,AData;
  166.   out dx,al
  167.   end;
  168. {$ENDIF}
  169.  
  170. {$IFDEF Target32Bit}
  171.   asm
  172.   out dx,al
  173.   end;
  174. {$ENDIF}
  175.  
  176.  
  177. function ReadIOByte( AAddress : word) : byte; assembler;
  178. {$IFDEF Target16Bit}
  179.   asm
  180.   mov dx,AAddress;
  181.   in al,dx
  182.   end;
  183. {$ENDIF}
  184.  
  185. {$IFDEF Target32Bit}
  186.   asm
  187.   mov dx,ax
  188.   in al,dx
  189.   end;
  190. {$ENDIF}
  191.  
  192.  
  193.  
  194.  
  195. procedure PPPRInitialise( APortAddress : word );
  196. { Opens the printer port setting defaults }
  197. begin
  198.   w_PPTAdr := APortAddress;
  199.   PPPRSetDefaults;
  200. end;
  201.  
  202.  
  203. procedure PPPRClearAllBits;
  204. { Sets the port to all data bits = 0 }
  205. begin
  206.   PPPRWriteAllBits( 0 );
  207. end;
  208.  
  209. procedure PPPRSetAllBits;
  210. { Sets the port to all data bits = 1 }
  211. begin
  212.   PPPRWriteAllBits( $FF );
  213. end;
  214.  
  215.  
  216. procedure PPPRToggleAllBits;
  217. { Complements all data bits }
  218. begin
  219.   PPPRWriteAllBits( by_PPPRExistingPattern xor $FF );
  220. end;
  221.  
  222.  
  223. procedure PPPRWriteAllBits( APattern : byte );
  224. { Sets this pattern on the data }
  225. begin
  226.   WriteIOByte( APattern, w_PPTAdr );
  227.   by_PPPRExistingPattern := APattern;
  228. end;
  229.  
  230.  
  231. procedure PPPRSetDefaults;
  232. { Sets the port into a defined state }
  233. begin
  234.   PPPRClearAllBits;
  235. end;
  236.  
  237.  
  238. function  bfunc_PPPRBusyIsHigh : boolean;
  239. { Returns TRUE if the busy input is high }
  240. begin
  241.   bfunc_PPPRBusyIsHigh :=
  242.     (ReadIOByte( w_PPTAdr + 1 {Status reg} ) and $80) <> 0;
  243. end;
  244.  
  245. function  bfunc_PPPRBusyIsLow : boolean;
  246. { Returns TRUE if the busy input is low }
  247. begin
  248.   bfunc_PPPRBusyIsLow := not bfunc_PPPRBusyIsHigh;
  249. end;
  250.  
  251. {$ElSE}
  252.  
  253.  
  254. procedure PPPRInitialise;
  255. { Opens the printer port setting defaults }
  256. begin
  257. end;
  258.  
  259. procedure PPPRSetAllBits;
  260. { Sets the port to all data bits = 1 }
  261. begin
  262. end;
  263.  
  264. procedure PPPRClearAllBits;
  265. { Sets the port to all data bits = 0 }
  266. begin
  267. end;
  268.  
  269. procedure PPPRToggleAllBits;
  270. { Complements all data bits }
  271. begin
  272. end;
  273.  
  274. procedure PPPRWriteAllBits( APattern : byte );
  275. { Sets this pattern on the data }
  276. begin
  277. end;
  278.  
  279. function  bfunc_PPPRBusyIsHigh : boolean;
  280. { Returns TRUE if the busy input is high }
  281. begin
  282. end;
  283.  
  284. function  bfunc_PPPRBusyIsLow : boolean;
  285. { Returns TRUE if the busy input is low }
  286. begin
  287. end;
  288.  
  289. procedure PPPRSetDefaults;
  290. { Sets the port into a defined state }
  291. begin
  292. end;
  293.  
  294.  
  295.  
  296.  
  297. {$ENDIF}
  298.  
  299.  
  300.  
  301. { End of PrinterPort profiler }
  302. { ---------------------------------------------------------------- }
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310. { Timing profiler }
  311. { ---------------------------------------------------------------- }
  312.  
  313.  
  314. {$IFDEF TMPR }
  315.  
  316. type
  317.   TTMPRRec = record
  318.    i_code  : integer;
  319.    r_Count : TLargeInteger;
  320.   end;
  321.  
  322. const
  323.  i_TMPRAbsMaxNumItems = 65520 div SizeOf( TTMPRRec );
  324.  
  325. type
  326.   TTMPRDataArray = array[0..i_TMPRAbsMaxNumItems] of TTMPRRec;
  327.   PTMPRDataArray = ^TTMPRDataArray;
  328.  
  329. const
  330.   r_TMPRData     : PTMPRDataArray = nil;
  331.   r_TMPRStart    : TLargeInteger = (QuadPart : 0);
  332.   i_TMPRNumItems : integer = 0;
  333.   i_TMPRMaxItems : integer = 0;
  334.   s_TMPRFileName : PString = nil;
  335.  
  336. procedure TMPROpen( const AFileName : string;
  337.                           AMaxItems : integer );
  338. { Opens the timing profiler }
  339. begin
  340.   If r_TMPRData <> nil then
  341.     TMPRClose;
  342.  
  343.   i_TMPRMaxItems := AMaxItems;
  344.   i_TMPRNumItems := 0;
  345.   s_TMPRFileName := NewStr( AFileName );
  346.  
  347.   { Create the data store }
  348.   GetMem( r_TMPRData, SizeOf( TTMPRRec ) * i_TMPRMaxItems );
  349.  
  350.   TMPRStart;
  351. end;
  352.  
  353.  
  354.  
  355. procedure TMPRStart;
  356. { Resets the timing profiler }
  357. begin
  358.   QueryPerformanceCounter( r_TMPRStart );
  359. end;
  360.  
  361.  
  362.  
  363. procedure TMPRMark( ACode : integer );
  364. { Marks this profile point }
  365. begin
  366.   If (r_TMPRData = nil)
  367.      or (i_TMPRNumItems >= i_TMPRMaxItems) then Exit;
  368.  
  369.   With r_TMPRData^[ i_TMPRNumItems ] do
  370.     begin
  371.     i_Code  := ACode;
  372.     QueryPerformanceCounter(r_Count);
  373.     end;
  374.   Inc( i_TMPRNumItems );
  375.  
  376. end;
  377.  
  378.  
  379.  
  380. procedure TMPRClose;
  381. { Closes the timing profiler }
  382. var
  383.  F                   : text;
  384.  f_CountsPerMS       : double;
  385.  f_OffsetMS          : double;
  386.  f_LastOffsetMS      : double;
  387.  f_DiffMS            : double;
  388.  
  389.    procedure FormatMark( ACode     : integer;
  390.                          AOffsetMS : double;
  391.                          ADiffMS   : double );
  392.    begin
  393.      Write( F, 'Ref:'        , ACode     : 5 );
  394.      Write( F, ', Abs (ms):' , AOffsetMS : 9 : 4 );
  395.      Write( F, ', Diff (ms):', ADiffMS   : 9 : 4 );
  396.      Writeln( F );
  397.    end;
  398.  
  399. var
  400.  I : integer;
  401. begin
  402.   If (r_TMPRData = nil)
  403.     or (s_TMPRFileName = nil) then Exit;
  404.  
  405.   f_CountsPerMS  := r_CountsPerSec.QuadPart / 1000;
  406.  
  407.   Assign( F, s_TMPRFileName^ );
  408.   Rewrite( F );
  409.   Writeln( F, 'Timing profile dump');
  410.   Writeln( F );
  411.  
  412.  
  413.   { Dump the data to the file }
  414.   For I := 0 to i_TMPRNumItems-1 do
  415.    With r_TMPRData^[I] do
  416.     begin
  417.     f_OffsetMS := (r_Count.QuadPart - r_TMPRStart.QuadPart) / f_CountsPerMS;
  418.     If I = 0 then
  419.       f_LastOffsetMS := f_OffsetMS;
  420.     f_DiffMS := f_OffsetMS - f_LastOffsetMS;
  421.     f_LastOffsetMS := f_OffsetMS;
  422.     FormatMark( i_Code,
  423.                 f_OffsetMS,
  424.                 f_DiffMS );
  425.     end;
  426.   Close( F );
  427.  
  428.   DisposeStr( s_TMPRFileName );
  429.  
  430.   { Dispose of the data store }
  431.   FreeMem( r_TMPRData, SizeOf( TTMPRRec ) * i_TMPRMaxItems );
  432.   r_TMPRData := nil;
  433. end;
  434.  
  435.  
  436. {$ELSE }
  437.  
  438.  
  439.  
  440.  
  441. procedure TMPROpen;
  442. begin
  443. end;
  444.  
  445.  
  446.  
  447. procedure TMPRStart;
  448. { Resets the timing profiler }
  449. begin
  450. end;
  451.  
  452.  
  453.  
  454. procedure TMPRMark( ACode : integer );
  455. { Marks this profile point }
  456. begin
  457. end;
  458.  
  459.  
  460.  
  461. procedure TMPRClose;
  462. { Closes the timing profiler }
  463. begin
  464. end;
  465.  
  466.  
  467. {$ENDIF }
  468.  
  469.  
  470. { End of Timing profiler }
  471. { ---------------------------------------------------------------- }
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482. var
  483.   ExitSave : pointer;
  484.  
  485.    procedure MyExitProc; FAR;
  486.    begin
  487.    end;
  488.  
  489.  
  490. begin
  491.   ExitSave := ExitProc;
  492.   ExitProc := @MyExitProc;
  493. end.
  494.